home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
news
/
readers
/
nn-tk.001
/
nn-tk~
/
nn
/
unshar.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-25
|
6KB
|
192 lines
/****************************************************************
* unshar.c: Unpackage one or more shell archive files
*
* Description: unshar is a filter which removes the front part
* of a file and passes the rest to the 'sh' command.
* It understands phrases like "cut here", and also
* knows about shell comment characters and the Unix
* commands "echo", "cat", and "sed".
*
* HISTORY
* 27-July-88 Kim F. Storm (storm@texas.dk) Texas Instruments, Denmark
* Adapted to :unshar command in nn
* Added static to function declarations
* Removed all unused functions, i.e. not useful as stand-alone pgm.
* 29-Jan-85 Michael Mauldin (mlm) at Carnegie-Mellon University
* Created.
****************************************************************/
#include "config.h"
/* unshar.c */
static int stlmatch __APROTO((char *big, char *small));
static int smatch __APROTO((register char *dat, register char *pat, register char **res));
extern long ftell ();
/*****************************************************************
* stlmatch -- match leftmost part of string
*
* Usage: i = stlmatch (big,small)
* int i;
* char *small, *big;
*
* Returns 1 iff initial characters of big match small exactly;
* else 0.
*
* HISTORY
* 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
* Ripped out of CMU lib for Rog-O-Matic portability
* 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University
* Rewritten for VAX from Ken Greer's routine.
*
* Originally from klg (Ken Greer) on IUS/SUS UNIX
*****************************************************************/
static int stlmatch (big, small)
char *small, *big;
{ register char *s, *b;
s = small;
b = big;
do
{ if (*s == '\0')
return (1);
}
while (*s++ == *b++);
return (0);
}
/*****************************************************************
* smatch: Given a data string and a pattern containing one or
* more embedded stars (*) (which match any number of characters)
* return true if the match succeeds, and set res[i] to the
* characters matched by the 'i'th *.
*****************************************************************/
static int
smatch (dat, pat, res)
register char *dat, *pat, **res;
{
register char *star = 0, *starend = 0, *resp = 0;
int nres = 0;
while (1)
{ if (*pat == '*')
{ star = ++pat; /* Pattern after * */
starend = dat; /* Data after * match */
resp = res[nres++]; /* Result string */
*resp = '\0'; /* Initially null */
}
else if (*dat == *pat) /* Characters match */
{ if (*pat == '\0') /* Pattern matches */
return (1);
pat++; /* Try next position */
dat++;
}
else
{ if (*dat == '\0') /* Pattern fails - no more */
return (0); /* data */
if (star == 0) /* Pattern fails - no * to */
return (0); /* adjust */
pat = star; /* Restart pattern after * */
*resp++ = *starend; /* Copy character to result */
*resp = '\0'; /* null terminate */
dat = ++starend; /* Rescan after copied char */
}
}
}
/****************************************************************
* position: position 'fil' at the start of the shell command
* portion of a shell archive file.
* Kim Storm: removed static variables
****************************************************************/
int
unshar_position (fil)
FILE *fil;
{
char buf[BUFSIZ];
long pos;
/* Results from star matcher */
char res1[BUFSIZ], res2[BUFSIZ], res3[BUFSIZ], res4[BUFSIZ];
char *result[4];
result[0] = res1, result[1] = res2, result[2] = res3, result[3] = res4 ;
/* rewind (fil); */
while (1) {
/* Record position of the start of this line */
pos = ftell (fil);
/* Read next line, fail if no more */
if (fgets (buf, BUFSIZ, fil) == NULL) {
msg("no shell commands in file");
return (0);
}
/* Bail out if we see C preprocessor commands or C comments */
if (stlmatch (buf, "#include") || stlmatch (buf, "# include") ||
stlmatch (buf, "#define") || stlmatch (buf, "# define") ||
stlmatch (buf, "#ifdef") || stlmatch (buf, "# ifdef") ||
stlmatch (buf, "#ifndef") || stlmatch (buf, "# ifndef") ||
stlmatch (buf, "/*"))
{
msg("file looks like raw C code, not a shar file");
return (0);
}
/* Does this line start with a shell command or comment */
if (stlmatch (buf, "#") ||
stlmatch (buf, ":") ||
stlmatch (buf, "echo ") ||
stlmatch (buf, "sed ") ||
stlmatch (buf, "cat "))
{
fseek (fil, pos, 0);
return (1);
}
/* Does this line say "Cut here" */
if (smatch (buf, "*CUT*HERE*", result) ||
smatch (buf, "*cut*here*", result) ||
smatch (buf, "*TEAR*HERE*", result) ||
smatch (buf, "*tear*here*", result) ||
smatch (buf, "*CUT*CUT*", result) ||
smatch (buf, "*cut*cut*", result))
{
/* Read next line after "cut here", skipping blank lines */
while (1) {
pos = ftell (fil);
if (fgets (buf, BUFSIZ, fil) == NULL) {
msg("no shell commands after 'cut'");
return (0);
}
if (*buf != '\n') break;
}
/*
* Win if line starts with a comment character of
* lower case letter
*/
if (*buf == '#' ||
*buf == ':' ||
(('a' <= *buf) && ('z' >= *buf))) {
fseek (fil, pos, 0);
return (1);
}
/* Cut here message lied to us */
msg("invalid data after CUT line");
return (0);
}
}
}